<template>
    <div class="vc-ellipsis">
        <div v-if="!$slots.default"
            ref="wrapRef"
            class="vc-ellipsis-content"
            :class="{
                'is-label': isLabel,
                'is-checked': checked,
                'is-shade': shade,
            }"
            v-html="content || ''"
            :style="styl">
        </div>

        <div v-if="$slots.default"
            ref="wrapRef"
            class="vc-ellipsis-content"
            :class="{
                'is-label': isLabel,
                'is-checked': checked,
                'is-shade': shade,
            }"
            :style="styl">
            <slot />
        </div>


        <div v-if="isLabel"
            class="vc-ellipsis-label"
            :class="{
                'is-checked': checked
            }"
            :style="{ justifyContent: labelAlign }">
            <button :style="labelStyle"
                :class="{ 'label-hover': labelHover }"
                @click="onExpand">
                {{ checked ? noExpandText : expandText }}
                <svg viewBox="64 64 896 896"
                    width="1em"
                    height="1em"
                    fill="currentColor"
                    aria-hidden="true"
                    focusable="false">
                    <path
                        d="M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512 181.7 851.1A7.98 7.98 0 0 0 188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512 485.7 851.1A7.98 7.98 0 0 0 492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z">
                    </path>
                </svg>
            </button>
        </div>
    </div>
</template>

<script>
export default {
    props: {
        maxHeight: {
            type: String,
            default: '200px',
        },
        // rows: {
        //     type: Number,
        //     default: 3,
        // },
        content: {
            type: String,
            default: ''
        },
        labelStyle: {
            type: Object,
            default: () => ({})
        },
        labelHover: {
            type: Boolean,
            default: false
        },
        labelAlign: {
            type: String,
            default: 'center'
        },
        stop: {
            type: Boolean,
            default: false
        },
        expandText: {
            type: String,
            default: '展开',
        },
        noExpandText: {
            type: String,
            default: '收起',
        },
        shade: {
            type: Boolean,
            default: true
        },
    },
    data: () => ({
        checked: false,
        isLabel: false,
        ob: null,
    }),
    computed: {
        styl() {
            const ell = {
                // "-webkit-line-clamp": this.rows,
                // 'text-overflow': 'ellipsis',
                // 'display': '-webkit-box',
                // '-webkit-box-orient': 'vertical',
            }
            let styl = {}
            if (this.checked) {
                styl.maxHeight = '5000px'
            } else {
                styl.maxHeight = this.maxHeight
                styl = {
                    ...styl,
                    ...ell,
                }
            }
            return styl
        },
    },
    mounted() {
        const wrap = this.$refs.wrapRef
        if (!this.ob) {
            const rOB = new ResizeObserver((entries) => {
                const rect = entries[0]?.contentRect
                if (!rect) return
                if (this.checked) {
                    if (!this.isLabel) this.isLabel = true
                } else {
                    this.isLabel = Math.ceil(rect.height) < Math.ceil(wrap.scrollHeight)
                }
            })
            rOB.observe(wrap)
            this.ob = Object.freeze(rOB)
        }
    },
    beforeUnmount() {
        this.ob.unobserve(this.$refs.wrapRef)
    },
    methods: {
        onExpand(e) {
            if (this.stop) {
                return
            }
            this.checked = !this.checked
            e.stopPropagation()
        },
    }
}
</script>

<style lang="scss" scoped>
.vc-ellipsis {
    --bg-color: #fff;
    width: 100%;
    overflow: hidden clip;

    .vc-ellipsis-content {
        overflow: hidden;
        position: relative;
        // transition: 0.4s max-height;
        font-size: inherit;
        word-break: break-all;
        overflow: hidden;
        // word-break: break-all;
        // overflow: hidden;
        // text-overflow: ellipsis;
        // display: -webkit-box;
        // -webkit-line-clamp: 3;
        // -webkit-box-orient: vertical;

        &.is-label.is-shade:not(.is-checked) {
            &::after {
                content: "";
                position: absolute;
                bottom: 0;
                display: block;
                width: 100%;
                height: 80px;
                background: linear-gradient(to bottom,
                        transparent 0,
                        rgba(255, 255, 255, 0.15) 10%,
                        rgba(255, 255, 255, 0.3) 20%,
                        var(--bg-color) 100%);
                pointer-events: none;
            }
        }
    }

    .vc-ellipsis-label {
        position: relative;
        display: flex;
        justify-content: center;
        align-items: center;

        button {
            display: inline-flex;
            justify-content: center;
            align-items: center;
            border: none;
            background-color: transparent;
            cursor: pointer;
            color: inherit;

            svg {
                font-size: 12px;
                transform: rotate(90deg);
                transition: all .2s;
                margin-left: 5px;
            }
        }

        .label-hover {
            &:hover {
                color: #1780ff;
            }
        }

        &.is-checked {
            button {
                svg {
                    transform: rotate(-90deg);
                }
            }
        }
    }
}
</style>